package mop.model.task.state;

import mop.exception.BusinessRule2Exception;
import mop.exception.BusinessRule3Exception;
import mop.exception.BusinessRule4Exception;
import mop.exception.RecursiveBusinessRule2Exception;
import mop.model.task.Task;

/**
 * factory mehtod pattern
 * @author ajhl
 *
 */
public class StateFactory 
{
		
	/**
	 * CreateState
	 * creates a state through the normal constructors
	 * 
	 * @param state
	 * 		the state you want constructed
	 * 
	 * @param t
	 * 	 	the task the state should be connected with  
	 * 
	 * @throws BusinessRule2Exception 
	 * 		| @see State.rule2isMet
	 * 
	 * @throws BusinessRule3Exception
	 * 		| @see State.rule3isMet
	 * 
	 * @throws RecursiveBusinessRule2Exception 
	 * 		| @see State.rule2Parents
	 * 
	 * @return the new State
	 */
	static public State createState(String state,Task t) throws BusinessRule2Exception,BusinessRule3Exception
	{
		if(state.equals(Successful.stateName()))
		{
			return new Successful(t);
		}
		else if(state.equals(Failed.stateName()))
		{
			return new Failed(t);
		}
		else if(state.equals(Unfinished.stateName()))
		{
			Unfinished temp = new Unfinished(t);
			return temp.refreshStatus();
		}
		else if(state.equals(Unavailable.stateName()))
		{
			return new Unavailable(t);
		}
		else if(state.equals(Available.stateName()))
		{
			return new Available(t);
		}
		else
			throw new IllegalArgumentException(state+" is not a valid argument !");
	}
	
	/**
	 * Create State without exceptions 
	 * this is what we call forcing
	 * 
	 * @param state
	 * 		the state you want to create
	 * 
	 * @param t
	 * 		the task to bind to the state
	 * 
	 * @return the new State
	 */
	static public State createUncheckedState(String state,Task t)
	{
		if(state.equals(Successful.stateName()))
		{
			return new Successful(t,true);
		}
		else if(state.equals(Failed.stateName()))
		{
			return new Failed(t,true);
		}
		else if(state.equals(Unfinished.stateName()))
		{
			Unfinished temp = new Unfinished(t,true);
			return temp.refreshStatus();
		}
		else if(state.equals(Unavailable.stateName()))
		{
			return new Unavailable(t,true);
		}
		else if(state.equals(Available.stateName()))
		{
			return new Available(t,true);
		}
		else
			throw new IllegalArgumentException(state+" is not a valid argument !");
	}
	
	/**
	 * Create a updated state
	 * @param state
	 * @param oldstate
	 * @return
	 * @throws BusinessRule2Exception
	 * @throws BusinessRule3Exception
	 * @throws RecursiveBusinessRule2Exception
	 */
	static public State createUpdatedState(String state,State oldstate) throws BusinessRule2Exception, BusinessRule3Exception, RecursiveBusinessRule2Exception,BusinessRule4Exception 
	{
		if(state.equals(Successful.stateName()))
		{
			return new Successful(oldstate);
		}
		else if(state.equals(Failed.stateName()))
		{
			return new Failed(oldstate);
		}
		else if(state.equals(Unfinished.stateName()))
		{
			Unfinished temp = new Unfinished(oldstate);
			return temp.refreshUpdateStatus();
		}
		else if(state.equals(Unavailable.stateName()))
		{
			return new Unavailable(oldstate);
		}
		else if(state.equals(Available.stateName()))
		{
			return new Available(oldstate);
		}
		else
			throw new IllegalArgumentException(state+" is not a valid argument !");
	}
}
